/*
 * Created on2022/6/11 15:54
 *
 * Copyright(c) YuZhou Big Data Laboratory CO.,Ltd, 2022.  All rights reserved.
 *
 *******************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ******************************************************************************/

package org.yzbdl.lanius.core.plugins.metastore;

import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import org.yzbdl.lanius.core.exception.LaniusEngineDbException;
import org.yzbdl.lanius.core.metastore.HutoolDb;

import com.google.common.collect.Lists;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.db.Entity;
import cn.hutool.db.handler.BeanHandler;

/**
 * TODO
 *
 * @author hs@yzbdl.ac.cn
 * @version 1.0
 * @date 2019/6/11 15:54
 */
public class LdrCategoryDao {

    private static LdrCategoryDao ldrCategoryDao = new LdrCategoryDao();

    private LdrCategoryDao() {}

    public static LdrCategoryDao getInstance() {
        return ldrCategoryDao;
    }

    /**
     * 添加
     *
     * @param obj
     * @return
     * @throws LaniusEngineDbException
     */
    public LdrCategoryEntity save(LdrCategoryEntity obj) throws LaniusEngineDbException {
        try {
            Entity entity = Entity.create("ldr_category").set("classification_id", obj.getClassificationId())
                .set("plugin_type_class", obj.getPluginTypeClass()).set("name", obj.getName())
                .set("expanded", obj.getExpanded()).set("create_time", obj.getCreateTime())
                .set("sort_num", obj.getSortNum());
            Long id = HutoolDb.useDynamicUrlDb().insertForGeneratedKey(entity);
            obj.setId(id.intValue());
            return obj;
        } catch (SQLException e) {
            throw new LaniusEngineDbException(e);
        }
    }

    /**
     * 修改
     *
     * @param obj
     * @return
     * @throws LaniusEngineDbException
     */
    public LdrCategoryEntity update(LdrCategoryEntity obj) throws LaniusEngineDbException {
        try {
            HutoolDb.useDynamicUrlDb().update(Entity.create("ldr_category").parseBean(obj, true, false),
                Entity.create("ldr_category").set("id", obj.getId()));
            return obj;
        } catch (SQLException e) {
            throw new LaniusEngineDbException(e);
        }
    }

    /**
     * 修改
     *
     * @param categoryId
     * @param newName
     * @return
     * @throws LaniusEngineDbException
     */
    public void update(Integer categoryId, String newName) throws LaniusEngineDbException {
        try {
            HutoolDb.useDynamicUrlDb().execute("UPDATE ldr_category SET NAME = ? WHERE ID = ?", newName, categoryId);
        } catch (SQLException e) {
            throw new LaniusEngineDbException(e);
        }
    }

    /**
     * 删除
     *
     * @param id
     */
    public synchronized void delete(Integer id) throws LaniusEngineDbException {
        try {
            HutoolDb.useDynamicUrlDb().del("ldr_category", "id", id);
        } catch (SQLException e) {
            throw new LaniusEngineDbException(e);
        }
    }

    /**
     * 获取某个类别下面的所有分组
     *
     * @param classificationId
     * @return
     * @throws LaniusEngineDbException
     */
    public List<LdrCategoryEntity> getAllByClassificationId(Integer classificationId) throws LaniusEngineDbException {
        try {
            String sql =
                "select * from ldr_category where classification_id = ? order by sort_num asc, create_time desc, name asc";
            return HutoolDb.useDynamicUrlDb().query(sql, LdrCategoryEntity.class, classificationId);
        } catch (SQLException e) {
            throw new LaniusEngineDbException(e);
        }
    }

    public LdrCategoryEntity getOne(Integer classificationId, String name) throws LaniusEngineDbException {
        try {
            return HutoolDb.useDynamicUrlDb().query(
                "select * from ldr_category where classification_id = ? and name = ? order by create_time desc",
                new BeanHandler<LdrCategoryEntity>(LdrCategoryEntity.class), classificationId, name);
        } catch (SQLException e) {
            throw new LaniusEngineDbException(e);
        }
    }

    public LdrCategoryEntity getOne(Integer id) throws LaniusEngineDbException {
        try {
            List<LdrCategoryEntity> categoryEntities = HutoolDb.useDynamicUrlDb()
                .query("select * from ldr_category where id = ? ", LdrCategoryEntity.class, id);
            if (null == categoryEntities || categoryEntities.size() <= 0)
                return null;
            return categoryEntities.get(0);
        } catch (SQLException e) {
            throw new LaniusEngineDbException(e);
        }
    }

    /**
     * 更新所有的展开状态
     *
     * @param expand
     * @param ids
     */
    public void updateExpandStatus(boolean expand, Integer... ids) throws LaniusEngineDbException {
        try {
            List<Object> params = Lists.newArrayList();

            StringBuffer sql = new StringBuffer("update ldr_category set expanded = ? ");
            params.add(expand);

            if (ids != null && ids.length > 0) {
                sql.append("where id in (");
                for (int i = 0; i < ids.length; i++) {
                    sql.append(" ?,");
                    params.add(ids[i]);
                }
                sql.deleteCharAt(sql.length() - 1);
                sql.append(" )");
            }

            HutoolDb.useDynamicUrlDb().execute(sql.toString(), ArrayUtil.toArray(params, Object.class));
        } catch (SQLException e) {
            throw new LaniusEngineDbException(e);
        }
    }

    public void deleteByClassificationId(Integer classificationId) throws LaniusEngineDbException {
        try {
            HutoolDb.useDynamicUrlDb().del("ldr_category", "classification_id", classificationId);
        } catch (SQLException e) {
            throw new LaniusEngineDbException(e);
        }
    }

    public void updateCategory(String description, String pluginTypeClass, Integer sortNum, Integer classficationId)
        throws LaniusEngineDbException {
        try {
            String sql = "select * from ldr_category where name = ? and plugin_type_class=?";
            String updateSql = "update ldr_category  set sort_num= ? where id=?";
            List<LdrCategoryEntity> list =
                HutoolDb.useDynamicUrlDb().query(sql, LdrCategoryEntity.class, description, pluginTypeClass);
            if (list.size() > 0) {
                for (int i = 0; i < list.size(); i++) {
                    List<Object> params = Lists.newArrayList();
                    params.add(sortNum);
                    params.add(list.get(i).getId());
                    HutoolDb.useDynamicUrlDb().execute(updateSql, ArrayUtil.toArray(params, Object.class));
                }
            } else {
                LdrCategoryEntity ldrCategoryEntity = new LdrCategoryEntity();
                ldrCategoryEntity.setSortNum(sortNum);
                ldrCategoryEntity.setClassificationId(classficationId);
                ldrCategoryEntity.setCreateTime(new Date());
                ldrCategoryEntity.setName(description);
                ldrCategoryEntity.setPluginTypeClass(pluginTypeClass);
                ldrCategoryEntity.setExpanded(false);
                save(ldrCategoryEntity);
            }
        } catch (SQLException e) {
            throw new LaniusEngineDbException(e);
        }
    }

    /**
     * 获取自定义分组最大的排序号
     *
     * @param pluginTypeClass 插件类别类的名称: BasePluginType的子类类名全称
     * @return
     * @throws LaniusEngineDbException
     */
    public Integer getCustomizeMaxSortNum(String pluginTypeClass, Integer id) throws LaniusEngineDbException {
        try {
            return HutoolDb.useDynamicUrlDb().query(
                "select max(sort_num) from ldr_category where plugin_type_class = ? and classification_id = ?",
                new BeanHandler<Integer>(Integer.class), pluginTypeClass, id);
        } catch (SQLException e) {
            throw new LaniusEngineDbException(e);
        }
    }
}
